import threading
import socket
import PySimpleGUI as sg
import paramiko
from all_Layout.base import base_layout
from all_Layout.main_lay import main_layout,cmd_list
from all_Layout.stitch_layout import st_lay
from Image_base64.image import run
import os
from Decorate_API.decorate import convert_to_bytes,ssh_connect
from Image_stitching.stitich import run_stitch
# from ros_control.car_go import Car_go

class Ros_car():
    def __init__(self):
        #  设置主题
        sg.ChangeLookAndFeel('Default1')
        layout = [
            [sg.Sizer(120, 1), sg.Text('基于无人车的果园个体树冠全景图快速生成系统', size=(38, 1), justification='center', font=("Helvetica", 16),
                                       k='-TEXT HEADING-')]]

        # 主窗口布局
        Mainlayout = [
            [main_layout, sg.VerticalSeparator(), sg.Column(base_layout)],
        ]
        layout += [[sg.TabGroup([[sg.Tab('主窗口', Mainlayout, metadata=run, ),
                                  sg.Tab('全景图拼接', st_lay)]],
                                key='-TAB GROUP-'), ]]
        # 设置前置窗口
        self.top_window = sg.Window('基于无人车的果园个体树冠全景图快速生成系统', layout, finalize=True, grab_anywhere=False, alpha_channel=1)
        # 定义类在其构造函数中启动小车控制节点
    def circle_event(self):
        # 由于拼接时间过长，拼接体验较差，因此通过多线程加入加载条
        # 线程标志位
        thread = None
        # 设置加载条刷新频率
        timeout = 100
        while True:
            self.event, self.values = self.top_window.read(timeout=100)
            try:
                if self.event == 'read_pic':
                    # 获取这个文件夹路径的所有图片文件路径
                    for index, pic_name in enumerate(os.listdir(self.values['input'])):  #
                        abs_pic_path = os.path.join(self.values['input'], pic_name)
                        index += 1
                        self.top_window['orininal_pic{}'.format(index)].update(
                            data=convert_to_bytes(abs_pic_path, (70, 150)))
            except FileNotFoundError:
                sg.popup_error('请选择小车拍摄图片路径！')
            try:
                if self.event == '-unfold-':
                    # 获取当前路径下的tree_image文件绝对路径
                    unfold_pic_path = os.path.abspath(os.path.dirname(__file__)) + r'/tree_images'
                    # enumerate创建索引让6个image窗口同时更新
                    for index, pic_name in enumerate(os.listdir(unfold_pic_path)):
                        abs_unfold_pic_path = os.path.join(unfold_pic_path, pic_name)
                        index += 1
                        self.top_window['handle_pic{}'.format(index)].update(
                            data=convert_to_bytes(abs_unfold_pic_path, (70, 150)))
            except FileNotFoundError:
                sg.popup_error('请先导入小车原始图片！')
            if self.event == '-join-' and not thread:
                # 加入一个子线程运行拼接程序，既能呈现加载又能运行程序
                thread = threading.Thread(target=run_stitch, args=(self.top_window,),
                                          daemon=True)
                thread.start()
                sg.popup_animated(sg.DEFAULT_BASE64_LOADING_GIF, background_color='white', transparent_color='white',
                                  time_between_frames=100, message='全景图生成中....')
            #     这个标志位是从run_stitch这个外部函数写入的
            if self.event == '-THREAD-':
                # 结束线程
                thread.join(timeout=0)
                # 结束加载条
                sg.popup_animated(None)
                # 清除标志位
                thread, timeout = None, None
                # 运行完子线程再进行下面的更新页面操作
                full_view_path = os.path.abspath(os.path.dirname(__file__)) + r'/join_pic'
                full_view_pic = os.path.join(full_view_path, os.listdir(full_view_path)[-1])
                self.top_window['full_view'].update(data=convert_to_bytes(full_view_pic, (750, 180)))
                sg.popup_ok('全景图生成成功！！！！！')
            #     不断更新加载条使其有动画
            if thread is not None:
                sg.popup_animated(sg.DEFAULT_BASE64_LOADING_GIF, background_color='white', transparent_color='white',
                                  time_between_frames=100, message='全景图生成中....')
            # ssh连接
            try:
                if self.event =='-connect-' and self.values['-ip-'] and self.values['-master_name-'] and self.values['-password-']:
                    re = ssh_connect(self.values['-ip-'],self.values['-master_name-'],self.values['-password-'])
                    if re:
                        sg.popup_ok('链接成功！！')
            except paramiko.ssh_exception.AuthenticationException:
                sg.popup_error('链接未成功请检查密码是否输入正确！')
            except socket.gaierror:
                sg.popup_error('请检查ip地址是否输入错误!')
            if self.event=='-disconnect-':
                sg.popup_ok('成功关闭链接！')
            #  运行节点
            if self.event == '-run-' and self.values['LB']:
                cmd =cmd_list.get(self.values['LB'][0],list(cmd_list.values())[0])
                if cmd=='car_control':
                    self.Car_go = Car_go()
                elif 'roslaunch' in cmd:
                    os.system(
                        "gnome-terminal -e 'bash -c \"sshpass -p 123456 ssh xrrobot@192.168.123.75 {}; exec bash\"'".format(cmd))
                else:
                    os.system(
                        "gnome-terminal -e 'bash -c \"{}; exec bash\"'".format(cmd))

            # 小车控制
            try:
                if self.event=='-FORWARD-':
                    self.Car_go.go_straight()
                if self.event=='-LEFT-':
                    self.Car_go.go_left()
                if self.event=='-RIGHT-':
                    self.Car_go.go_right()
                if self.event=='-DOWN-':
                    self.Car_go.go_back()
                if self.event=='-wSKIDER-' or self.event=='-rSKIDER-':
                    if self.event=='-wSKIDER-':
                        sg.popup_ok("角速度改变-{}".format(self.values['-wSKIDER-']))
                    if self.event=='-rSKIDER-':
                        sg.popup_ok("线速度改变-{}".format(self.values['-wSKIDER-']))
                    self.Car_go.change_speed(self.values['-rSKIDER-'],self.values['-wSKIDER-'])
            except AttributeError:
                sg.popup_error('请先启动小车控制节点')

            # 拍照控制
        # try:
            if self.event=='take_pic':
                self.Car_go.catch_pic()
                sg.popup_ok('拍照成功！！')
        # except:
        #     sg.popup_error('请先启动摄像头节点并开启拍照服务')

            if self.event in (None, 'Exit'):
                break
            if self.event != sg.TIMEOUT_EVENT:
                # if not a timeout event, then it's a button that's being held down
                self.top_window['-STATUS-'].update(self.event)
            else:
                # A timeout signals that all buttons have been released so clear the status display
                self.top_window['-STATUS-'].update('')
        self.top_window.close()


if __name__ == '__main__':
    ROS = Ros_car()
    ROS.circle_event()
